#include "com_mirror_surface.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <math.h>

#include <sys/param.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>

#include "com_mirror_rtp.h"
#include "com_mirror_rtcp.h"

#define ANDROID_V23_ANW_LOCK "ANativeWindow_lock"
#define ANDROID_V23_ANW_UNLOCK "ANativeWindow_unlockAndPost"
#define ANDROID_V23_ANW_GETWIDTH "ANativeWindow_getWidth"
#define ANDROID_V23_ANW_GETHEIGHT "ANativeWindow_getHeight"
#define ANDROID_V23_ANW_RELEASE "ANativeWindow_release"
#define ANDROID_V23_ANW_GET "ANativeWindow_fromSurface"
#define ANDROID_V23_ANW_SETBUFFERSGEOMETRY "ANativeWindow_setBuffersGeometry"

#define ANDROID_V22_ANW_LOCK "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEb"
#define ANDROID_V22_ANW_UNLOCK "_ZN7android7Surface13unlockAndPostEv"

using namespace android;

struct SurfaceInfo {  
  uint32_t w;  
  uint32_t h; 
  uint32_t s; 
  uint32_t usage;
  PixelFormat format;
  void* bits;
  uint32_t reserved[2];
  }; 


static SurfaceOperation g_surface_Opera;
static char *pPreBuffer = NULL; //图像数据缓存，读(刷新Surface)/写(JPEG解码结果)操作使用
static int flgRenew = HI_FAILURE; //可Surface更新标识，HI_FAILURE标示不需要更新,HI_SUCCESS标示需要更新
static int * lutW = NULL;
static int * lutH = NULL;
static const char *accessip = NULL;
static float DecodeTimeCost = 0;
char * recv_JpegAddr = NULL;    //当前接收数据的缓存位置
char * decode_JpegAddr = NULL;    //解压图像的缓存位置
pthread_mutex_t mutex;    //指示解码状态
int recv_length = 0;        //接收的数据长度
int DstLastHeight, DstLastWidth; //小屏幕上一次的长度和宽度

/////////////////////////////////////////////////////
//kRGB_565_Config image resize ,add by ywh ，未考虑插值
//输入参数中
//BytesPerPixel 为2 , 因为图像格式为kRGB_565_Config
static int ImageResize(char* SrcAddr ,char* DstAddr , int SrcWidth , int SrcHeight, int SrcStride ,
    int DstWidth , int DstHeight , int DstStride , int BytesPerPixel)
{
    if((NULL == SrcAddr) || (NULL == DstAddr))
    {
        return 0;
    }

    int i , j ;
    float ratioW , ratioH;
    char * psrc , * psrctemp, * pdst , *pdsttemp;

    //长宽变化时初始化
    if((NULL == lutW) || (DstLastHeight!=DstHeight) || (DstLastWidth!=DstWidth))
    {
        lutW = (int *)malloc(DstWidth*sizeof(int));
        lutH = (int *)malloc(DstHeight*sizeof(int));

        ratioW = (SrcWidth*1.0)/DstWidth;
        ratioH = (SrcHeight*1.0)/DstHeight;

        if(lutW == NULL || lutH == NULL)
        {
            if(lutW)
            {
                free(lutW);
                lutW = NULL;
            }
            if(lutH)
            {
                free(lutH);
                lutH = NULL;
            }
            return 0;
        }
        //LOGD("ImageResize Ratio W:%f" ,ratioW);
        for( i = 0 ; i < DstWidth ; i++)
        {
            lutW[i] = (int)(ratioW*i);
            //LOGD("ImageResize W:%d RW:%d" ,i , lutW[i]);
        }
        //LOGD("ImageResize Ratio H:%f" ,ratioH );
        for(i = 0 ; i < DstHeight; i++)
        {
            lutH[i] =  (int)(ratioH*i);

            //LOGD("ImageResize H:%d RH:%d" ,i , lutH[i]);
        }

        DstLastHeight=DstHeight;
        DstLastWidth=DstWidth;
    }

    //拷贝图像
    for( i = 0 ; i < DstHeight ; i++)
    {
        pdsttemp = DstAddr +    i    *DstStride*BytesPerPixel;
        psrctemp = SrcAddr + lutH[i]*SrcStride*BytesPerPixel;

        for( j = 0 ; j < DstWidth ; j++)
        {
            pdst = pdsttemp +    j   *BytesPerPixel;
            psrc = psrctemp + lutW[j]*BytesPerPixel;
            *pdst = *psrc;
            pdst ++;
            psrc ++;
            *pdst = *psrc;
        }
    }

    return 1;
}

// 将surface转化为ANativeWindow android <=2.2
static void* froyo_NativeRegisterSurface(void* pHandle,JNIEnv* env, jobject jsurface)
{
    jclass clazz = env->FindClass("android/view/Surface");
    jfieldID field_surface = env->GetFieldID(clazz, "mSurface", "I");
    if(field_surface == NULL)
    {
        return NULL;
    }
    return (void*)env->GetIntField(jsurface, field_surface);
}

// 更新 Surface for android <=2.2
static int froyo_NativeUpdateSurface(void* pPixels)
{
    //android::Surface::SurfaceInfo info;
    SurfaceInfo info;

    if (((android::Surface*)(g_surface_Opera.pSurfaceNative)) == NULL)
    {
        LOGE("pSurfaceNative error");
        return HI_FAILURE;
    }

    g_surface_Opera.pf_lock(g_surface_Opera.pSurfaceNative,&info,NULL); //g_surface_Opera.pf_lock(g_surface_Opera.pSurfaceNative,&info,1);


    if(HI_MIRROR_JPEG_MAX_WIDTH == info.w && HI_MIRROR_JPEG_MAX_HEIGHT == info.h)
    {
        //拷贝整块
        memcpy(info.bits, pPixels, info.w * info.h * BYTES_PER_PIXEL);
    }
    else
    {
        //尺寸变换,并拷贝整块图像
        ImageResize((char *)pPixels , (char *)info.bits
            , HI_MIRROR_JPEG_MAX_WIDTH , HI_MIRROR_JPEG_MAX_HEIGHT, HI_MIRROR_JPEG_MAX_WIDTH
        , info.w , info.h  , info.w , BYTES_PER_PIXEL);
    }
    //memcpy(info.bits, pPixels,  info.w * info.h * 2);

    g_surface_Opera.pf_unlockAndPost(g_surface_Opera.pSurfaceNative);
    //((android::Surface*)(g_surface_Opera.pSurfaceNative))->unlockAndPost();
    return HI_SUCCESS;
}

// 关闭库 android <=2.2
static int froyo_NativeUnRegisterSurface(void* pHandle)
{
    if(g_surface_Opera.pLibHandle)
    {
        dlclose(g_surface_Opera.pLibHandle);
    }
    return HI_SUCCESS;
}

// 载入动态链接库，只有安卓2.2需要 <=android 2.2
static inline void *LoadFroyoLib(const char *psz_lib)
{
    void *p_library = dlopen(psz_lib, RTLD_NOW);
    if (p_library)
    {
        g_surface_Opera.pf_lock = (PF_ANWindow_lock*)(dlsym(p_library, ANDROID_V22_ANW_LOCK));
        g_surface_Opera.pf_unlockAndPost = (PF_ANWindow_unlockAndPost*)(dlsym(p_library, ANDROID_V22_ANW_UNLOCK));
        if (g_surface_Opera.pf_lock && g_surface_Opera.pf_unlockAndPost)
        {
            return p_library;
        }
    }
    return NULL;
}

// 将surface转化为ANativeWindow android >=2.3
static void* ICS_NativeRegisterSurface(void* pHandle,JNIEnv* env, jobject jsurface)
{
    LOGD("before ICS regist surface");
    void* pWindow = g_surface_Opera.pf_get(env, jsurface);
    LOGD("after ICS regist surface : %x",pWindow);
    return pWindow;
}

//更新 Surface for android >=2.3
static int ICS_NativeUpdateSurface(void* pPixels)
{
    Surface_Buffer buffer; //lock后指向Surface的buffer
    // ARect *rect= (ARect*)malloc(sizeof(ARect));

    #if 1
    if(g_surface_Opera.pf_lock((g_surface_Opera.pSurfaceNative), &buffer, NULL) < 0)
    {
        LOGE("ICS g_surface_Opera_lock failed");
        return HI_FAILURE;
    }
    #else
    if(g_surface_Opera.pf_lock((g_surface_Opera.pSurfaceNative), &buffer, rect) < 0)
    {
        LOGE("ICS g_surface_Opera_lock failed");
        return HI_FAILURE;
    }
    #endif

    if (buffer.stride != buffer.width)
    {
        //LOGE("buffer.stride  %d != buffer.width  %d",buffer.stride,buffer.width);
        char* pSrc = (char*)pPixels;
        char* pDst = (char*)(buffer.bits);
        for (int i = 0; i < buffer.height; i++)
        {
            memcpy(pDst, pSrc, buffer.width* BYTES_PER_PIXEL);
            pDst += buffer.stride * BYTES_PER_PIXEL;
            pSrc += buffer.width* BYTES_PER_PIXEL;
        }
    }
    else
    {
        memcpy(buffer.bits, pPixels, buffer.width * buffer.height * BYTES_PER_PIXEL);
    }

    HI_S32 s32ret = g_surface_Opera.pf_unlockAndPost(g_surface_Opera.pSurfaceNative);
    if(s32ret < 0)
    {
        LOGE("ICS unlockAndPost Failed");
    }
    return s32ret;
}

// 关闭库 android >=2.3
static int ICS_NativeUnRegisterSurface(void* pHandle)
{
    g_surface_Opera.pf_release(g_surface_Opera.pSurfaceNative);
    if(g_surface_Opera.pLibHandle)
    {
        dlclose(g_surface_Opera.pLibHandle);
    }
    LOGD("AndroidNativeWindow_unregister end");
    return HI_SUCCESS;
}

// 获取当前时间-微秒
static int64_t gettime(void)
{
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}

inline void UpdateDecodeTime(float encodeTime)
{
    if(DecodeTimeCost < 1)
    {
        DecodeTimeCost = encodeTime;
    }
    else
    {
        DecodeTimeCost = 0.9*DecodeTimeCost + encodeTime*0.1;
    }
}

//JPEG解码并更新图片缓存 (pJpegAddr 指向的位置从自定义头开始，jpegLength 表示数据总长度，包含头部)
inline int JpegDecodeSkia(char* pBmpAddr,int jpegLength,char* pJpegAddr)
{
    SkBitmap bp;
    int bytesPerPixel;
    SkImageDecoder::Format fmt;
    //获取头结构
    HI_Mirror_JPEG_Head *JpegHead=(HI_Mirror_JPEG_Head*)pJpegAddr;

    //int64_t begintime,lasttime; //时间
    //begintime = gettime();


    //JPEG解码
    bool result = SkImageDecoder::DecodeMemory(pJpegAddr+HI_MIRROR_JPEG_HEAD_LENGTH,
                                                jpegLength-HI_MIRROR_JPEG_HEAD_LENGTH,
                                                &bp,SkBitmap::kNo_Config,
                                                SkImageDecoder::kDecodePixels_Mode,
                                                &fmt);

    //LOGD("SkImage Decode time = %lld",gettime() - begintime);

    if(!result)
    {
        LOGD("decoder file fail!");
        return HI_FAILURE;

    }
    else
    {
        if(fmt!= SkImageDecoder::kJPEG_Format)
        {

            LOGE("decoder file not jpeg!");
            return HI_FAILURE;

        }
        else
        {
            bytesPerPixel = bp.bytesPerPixel();
            char *pixl = (char*)bp.getPixels();

            //根据JPEG大小区分整张拷贝或区域拷贝
            if((HI_MIRROR_JPEG_MAX_WIDTH > JpegHead->Width) || (HI_MIRROR_JPEG_MAX_HEIGHT > JpegHead->Height))
            {
                //逐行拷贝
                for(int i=0;i<JpegHead->Height;i++)
                {
                    memcpy(pBmpAddr+((HI_MIRROR_JPEG_MAX_WIDTH*(JpegHead->y+i)) + JpegHead->x )*BYTES_PER_PIXEL, pixl+JpegHead->Width*i*BYTES_PER_PIXEL,  JpegHead->Width*BYTES_PER_PIXEL);
                }
            }
            else
            {
                memcpy(pBmpAddr, pixl, HI_MIRROR_JPEG_MAX_WIDTH * HI_MIRROR_JPEG_MAX_HEIGHT * BYTES_PER_PIXEL );
            }
        }

    }
    return bp.width() * bp.height() * bytesPerPixel;
}

#if 0
//解码时间统计
static int decodeLoop=0; //单块图片循环统计次数
static int jpegwidth=0; //换行宽度
int64_t decodeTime[15]={0}; //编码时间
int64_t normalTime[15]={0}; //正常值编码时间
static int jpegID = 0; //图片区块编号
#endif

// 图片数据处理(可能是一帧内变化区块的连续多个JPEG，也可能是完整一帧JPEG)
inline int ImageProcess(char *pBmp, int len, char *pJpeg)
{
    if ((NULL == pBmp) || (0 >= len) || (NULL == pJpeg))
    {
        LOGE("Image process failure.");
        return HI_FAILURE;
    }
    char* pBmpAddr=pBmp; //输出缓存
    int sum = len; // 图像数据总长度
    char *pJpegAddr = pJpeg; //输入JPEG, 没有去掉48字节头!

    HI_Mirror_JPEG_Head *JpegHead; //JPEG自定义头
    int ret; //解码后数据长度
    int64_t begintime, endtime;

    struct timeval StartTime, FinishTime ;
    float encodeTime;

    #if 0
    //实验统计
    int64_t begintime, endtime, sum10time, averagetime, variancetime, averagetime2; //时间
    double variance;
    //log 写入文件
    char pLogMsg[100];
    FILE* fpAverage = fopen("sdcard/zk/logAvg.txt","a+");
    FILE* fpVariance = fopen("sdcard/zk/logVar.txt","a+");
    FILE* fpDetal = fopen("sdcard/zk/logDetal.txt","a+");
    int i;

    //循环15次求均值
    if(decodeLoop>14)
    {
        jpegID++;
        decodeLoop = 0;
        sum10time=0;
        variancetime=0;

        //单个数据
        sprintf(pLogMsg,"####################\n");
        fwrite(pLogMsg,strlen(pLogMsg),1,fpDetal);
        fflush(fpDetal);

        //平均值
        for(i=0;i<15;i++)
        {
            sum10time+=decodeTime[i];
        }
        averagetime = sum10time/15;
        // sprintf(pLogMsg,"%10lld ",averagetime);
        // fwrite(pLogMsg,strlen(pLogMsg),1,fpAverage);

        //标准差
        for(i=0;i<15;i++)
        {
            variancetime+=(decodeTime[i]-averagetime)*(decodeTime[i]-averagetime);
        }
        variance=sqrt((double)variancetime/15);
        sprintf(pLogMsg,"%15f ",variance);
        fwrite(pLogMsg,strlen(pLogMsg),1,fpVariance);

        //标准差在一定范围
        if(variance < (averagetime/4))
        {
            int num_normal=0;
            //排除异常点后的均值
            for(i=0;i<15;i++)
            {
                //偏差在一定范围内才认为是正常编码时间
                if(averagetime>=decodeTime[i] && (averagetime-decodeTime[i])<(averagetime/5))
                {
                    normalTime[num_normal++]=decodeTime[i];
                }
                else if( averagetime<decodeTime[i] && (decodeTime[i]-averagetime)<(averagetime/5) )
                {
                    normalTime[num_normal++]=decodeTime[i];
                }
            }

            if(0!=num_normal)
            {
                averagetime2=0;
                for(i=0;i<num_normal;i++)
                {
                    averagetime2+=normalTime[i];
                }
            }
            else
            {
                //当正常编码个数num_normal为0时，特殊处理
                num_normal = 1;
                averagetime2=num_normal;
            }

            //如果均值为1说明没有正常编码，应该增大偏移范围
            sprintf(pLogMsg,"%10lld ",averagetime2/num_normal);
        }
        else
        {
            //标准差过大
            sprintf(pLogMsg,"%10d ",1);
        }
        fwrite(pLogMsg,strlen(pLogMsg),1,fpAverage);

        //换行
        jpegwidth++;
        if(jpegwidth>9)
        {
            jpegwidth=0;
            sprintf(pLogMsg,"\n");
            fwrite(pLogMsg,strlen(pLogMsg),1,fpAverage);
            fwrite(pLogMsg,strlen(pLogMsg),1,fpVariance);
        }

        fflush(fpAverage);
        fflush(fpVariance);
    }
    fclose(fpAverage);
    fclose(fpVariance);
    //实验统计结束。
    #endif

    while(sum > 0)
    {
        //开始时间!解码
        begintime = gettime();
        //gettimeofday(&StartTime, 0);
        //获取JPEG头指针
        JpegHead = (HI_Mirror_JPEG_Head*)pJpegAddr;
        //数据长度减少
        if (JpegHead->MetaLen > 0)
        {
            sum -=(HI_MIRROR_JPEG_HEAD_LENGTH + JpegHead->MetaLen);
        }
        else
        {
            LOGE("JpegHead->MetaLen <= 0");
            return HI_FAILURE;
        }
        //JPEG解码
        ret = JpegDecodeSkia(pBmpAddr, HI_MIRROR_JPEG_HEAD_LENGTH + JpegHead->MetaLen, pJpegAddr);

        //结束时间!解码
        endtime = gettime();
        //gettimeofday(&FinishTime, 0);
        //encodeTime = (FinishTime.tv_sec - StartTime.tv_sec)*1000.0+(FinishTime.tv_usec - StartTime.tv_usec) * 0.001;
        encodeTime = (endtime - begintime);
        //calculate the decode time
        //计算解码时间
        if(JpegHead->Height == HI_MIRROR_JPEG_MAX_HEIGHT
            && JpegHead->Width == HI_MIRROR_JPEG_MAX_WIDTH)
        {
            UpdateDecodeTime(encodeTime);
        }
        #if 0
        //保存历史数据
        if(jpegID == JpegHead->NTPtime)
        {
            decodeTime[decodeLoop++] = endtime-begintime;
            sprintf(pLogMsg,"#\n%d-jpeg %d B\ndecode time = %lld usec\n",jpegID, JpegHead->MetaLen, endtime-begintime);
            fwrite(pLogMsg,strlen(pLogMsg),1,fpDetal);
            fflush(fpDetal);
            fclose(fpDetal);
        }
        //解码错误
        if(-1 == ret)
        {
            LOGE("JpegDecodeSkia failed!");
        }
        #endif

        //移动指针
        pJpegAddr += (HI_MIRROR_JPEG_HEAD_LENGTH + JpegHead->MetaLen);
    }

    #if 0
    endtime = gettime();
    LOGD("while in func Image Process, time:%lld", (endtime-begintime));
    #endif

    return HI_SUCCESS;
}

//RTP接收线程
static void* native_receive_process(void* args)
{
    LOGE("native_receive_process");
    int64_t begintime,endtime1,endtime2; //时间

    if(NULL == pPreBuffer)
    {
        pPreBuffer = (char*)malloc(HI_MIRROR_PRE_BUFFER_LENGTH);
        if (NULL == pPreBuffer)
        {
            LOGE("pPreBuffer : %x", pPreBuffer);
            return NULL;
        }
    }
    memset(pPreBuffer,0,HI_MIRROR_PRE_BUFFER_LENGTH);

    //RTP解包
    int loopNum = 0; // 剩余循环次数
    int sum = 0; // 图像数据总长度
    //int headLen = 12;
    int bodyLen = 0; // 单个图像片段长度

    RTPHeader *rtpHeadMsg = NULL; //RTP头
    unsigned short seq ; //当前序号
    unsigned short PrevSeq; //上一序号
    unsigned short rtpFlg=0; //1表示开始正常保存JPEG图片数据, 0表示没有启动
    int mark; //RTP结束包标识

    //init socket
    struct sockaddr_in servaddr;
    int sockfd=-1, n, dataLen;
    socklen_t servaddr_len;
    HI_S32 keepalive=1;
    HI_S32 s32Ret = HI_FAILURE;

    //init rtp packet count
    HI_U16 packet_interval = RTCP_STATISTIC_INTERVAL;
    HI_U16 weight_lost_rtp_num = 0;
    HI_U16 start_count_seq = 0;
    HI_U16 cur_seq = 0;
    HI_U16 recv_rtp_num = 0;

//init params for count frame

    HI_U16 receive_frame = 0;
    HI_U16 show_frame = 0;
    int64_t pre_count_time = 0;
    int64_t current_count_time = 0;
    int64_t count_time = 0;

    //init  params for data
    int receive_total_data = 0;
    HI_RTCP_Handler * rtcphandle = NULL;



    if(NULL == (rtcphandle = (HI_RTCP_Handler *)malloc(sizeof(HI_RTCP_Handler))))

    {
        LOGE("rtcphandle malloc fail");
        return NULL;

    }
    memset(rtcphandle,0,sizeof(HI_RTCP_Handler));

    s32Ret = Init_Rtcp_Udp(rtcphandle, accessip, CLIENT_TRANSMIT_PORT+1,CLIENT_TRANSMIT_PORT+1);

    if(HI_FAILURE == s32Ret)
    {
        LOGE("RtcpUdpInit fail ");
        return NULL;
    }

    fd_set read_fds;
    struct timeval TimeoutVal;

    char * recvs = (char *)malloc(RTP_MSG_LEN);

    if (NULL == recvs)
    {
        LOGE("receive buffer is NULL.");
        return NULL;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)
    {
        LOGE("udp socket error\n");
        free(recvs);
        return NULL;
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    servaddr.sin_port = htons(CLIENT_TRANSMIT_PORT);

    if(SOCKET_BIND_ERROR == bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)))
    {
        LOGE("udp bind error.");
        close(sockfd);
        free(recvs);
        return NULL;
    }
    else
    {
        s32Ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &keepalive, sizeof(keepalive));
        if (SOCKET_OPTION_REUSE_ERROR == s32Ret)
        {
            close(sockfd);
            free(recvs);
            LOGE("set socket option reuse error.");
            return NULL;
        }
    }

    //显示状态为RUN时，接收RTP包，组成JPEG图形数据
    while(DISPLAY_STATUS_RUN == g_surface_Opera.status)
    {
        FD_ZERO(&read_fds);
        FD_SET(sockfd, &read_fds);

        //add for statics frame rate
        current_count_time= gettime();
        count_time = current_count_time - pre_count_time;
        if(count_time > FRAME_TIME_INTERVAL_IN_USECOND)
        {
            pre_count_time = current_count_time;
            //print frame rate and receive frame
            //LOGD("receive Frame = %d , show Frame=%d  in %lld usec", receive_frame, show_frame, count_time);
            //print receive data
            //LOGD("receive data = %d KB in %lld usec", receive_total_data/KBYTE_IN_BYTE,count_time);
            receive_frame = 0;
            show_frame = 0;
            receive_total_data = 0;
        }

        //socket超时1s
        TimeoutVal.tv_sec  = 1;
        TimeoutVal.tv_usec = 0;
        s32Ret = select(sockfd+1, &read_fds, 0, 0, &TimeoutVal);
        if ( s32Ret <= 0)
        {
            //没有收到数据
            continue;
        }
        else
        {
            //LOGE("FD_ISSET");
            /*lint -e573  -e737 -e778*/
            if(false == FD_ISSET(sockfd, &read_fds))
            {
                LOGE("FD_ISSET error");
                close(sockfd);
                free(recvs);
                return NULL;
            }
            /*lint +e573  +e737 +e778*/

            memset(recvs,0,sizeof(recvs));
            dataLen = recvfrom(sockfd, (char *)(recvs),RTP_MSG_LEN, 0, NULL, 0);
            if(dataLen < RTP_HEADER_SIZE)
            {
                //接收的RTP包长度小于头的长度
                LOGE("dataLen < RTP_HEADER_SIZE");
                continue ;
            }

            // 1-读取RTP头信息
            rtpHeadMsg = (RTPHeader*)recvs;
            mark = rtpHeadMsg->marker; //结束标识
            bodyLen = dataLen - RTP_HEADER_SIZE; // 数据包内，载荷长度
            seq = rtpHeadMsg->sequencenumber; //序号
            //LOGD("seq=%d, mark=%d, bodyLen= %d", seq, mark, bodyLen);
            if(mark == 1)
            {
                //receive one frame
                receive_frame++;
            }

            receive_total_data = receive_total_data+dataLen;
            recv_rtp_num++;

            //if send packet interval num arrive RTCP_STATISTIC_INTERVAL
            if((HI_U16)(seq - start_count_seq) >= RTCP_STATISTIC_INTERVAL)
            {
                //send rtcp
                //LOGD("seq=%d, recv_rtp_num=%d,start_count_seq = %d", seq, recv_rtp_num,start_count_seq);
                //HI_S32 s32Ret = HI_FAILURE;
                HI_U16 cur_lost_num = (HI_U16)(RTCP_STATISTIC_INTERVAL - recv_rtp_num) % RTCP_STATISTIC_INTERVAL;
                if (0 == start_count_seq)
                {
                    //first statistic
                    weight_lost_rtp_num = cur_lost_num;
                }

                weight_lost_rtp_num = Cal_weighted_lost_num(cur_lost_num,weight_lost_rtp_num);
                rtcphandle->rtcppacket.payload.lost_rtp_num = weight_lost_rtp_num;
                rtcphandle->rtcppacket.payload.lost_rtp_interval = RTCP_STATISTIC_INTERVAL;
                rtcphandle->rtcppacket.payload.afford_frame_rate = HI_NativeSurface_GetDecodeFPS();
                rtcphandle->rtcppacket.payload.padding_reserve = 0;
                // print lost rtp num and afford frame rate
                LOGD("lost_rtp_num=%d, lost_rtp_interval=%d,afford_frame_rate =%d", rtcphandle->rtcppacket.payload.lost_rtp_num,
                        rtcphandle->rtcppacket.payload.lost_rtp_interval,rtcphandle->rtcppacket.payload.afford_frame_rate);
                Send_Rtcp_Udp(rtcphandle);
                start_count_seq = seq;
                recv_rtp_num = 0;
            }
            // 2-内容数据从上次的位置写入 pJpegAddr
            if (mark == 1 && rtpFlg==0)
            {
                //第一次到结束包，下个包为一帧的第一个包
                //LOGD("end mark");
                rtpFlg=1;
                sum = 0;

            }
            else if (rtpFlg==1)
            {
                //遇到第一个结束包之后的包
                if (seq==(PrevSeq+1))
                {
                    //LOGD("seq in order");
                    if ( NULL != recv_JpegAddr)
                    {
                        memcpy(recv_JpegAddr + sum,(recvs + RTP_HEADER_SIZE), bodyLen);
                        //拷贝数据，长度增加
                        sum += bodyLen;
                        //LOGD("sum=%d",sum);
                    }
                }
                else
                {
                    //接收的包序号不正确
                    //LOGD("RTP SEQ Error, seq=%d, prevSeq=%d",seq,PrevSeq);
                    sum = 0;
                    rtpFlg=0;
                    //丢包处理
                    //丢包一般是连续的，可以通知服务端重传（增加开销），或者服务端周期发送完整帧
                    // ...
                    continue;
                }
            }
            else
            {
                //rtpFlg为0，又不是结束包，则不处理
                continue;
            }
            //保存该RTP包序号，供下次RTP完整性检查
            //LOGD("PrevSeq=%d",PrevSeq);
            PrevSeq = seq;

            // 3-拼接图片
            if (mark == 1  && rtpFlg==1 && sum > 0)
            {
                if ((NULL != decode_JpegAddr) && (NULL != recv_JpegAddr))
                {
                    char * addr_temp;
                    pthread_mutex_lock (&mutex);
                    addr_temp = recv_JpegAddr;
                    recv_JpegAddr = decode_JpegAddr;
                    decode_JpegAddr = addr_temp;
                    recv_length = sum;
                    pthread_mutex_unlock(&mutex);
                }
                show_frame++;

                sum = 0;    // 字节位数置零
                rtpFlg=1;    // RTP开始标识  0仅适用于单RTP包的数据,1通用
            }
        }
    }

    //必须关闭
    close(sockfd);

    DeInit_Rtcp_Udp(rtcphandle);
    rtcphandle = NULL;

    if(NULL != recvs)
    {
        free(recvs);
        recvs = NULL;
    }

    return HI_SUCCESS;
}

//解码线程
static void* native_decode_process(void* args)
{
    int recv_length_temp = 0;
    while(DISPLAY_STATUS_RUN == g_surface_Opera.status)
    {
        pthread_mutex_lock (&mutex);
        if(recv_length > 0)
        {
            recv_length_temp = recv_length;
            recv_length = 0;
            // 解码并显示图像/
            #if 1
            //处理连续多张JPEG解码
            flgRenew = ImageProcess(pPreBuffer, recv_length_temp, decode_JpegAddr);
            #else
            //处理单张JPEG
            JpegDecodeSkia(pPreBuffer, recv_length_temp, decode_JpegAddr);
            #endif

            //g_surface_Opera.pf_update(pPreBuffer); //不再独立线程刷新效果测试

            pthread_mutex_unlock(&mutex);
        }
        else
        {
            pthread_mutex_unlock(&mutex);
            usleep(5);
        }
    }
    return HI_SUCCESS;
}

//屏幕刷新
static void* surface_auto_renew(void* args)
{
    HI_S32 s32ret;
    int64_t begintime,lasttime; //时间
    HI_S32 renewTimes=0; //刷新次数，测试用

    flgRenew = HI_FAILURE;

    while(DISPLAY_STATUS_RUN == g_surface_Opera.status)
    {
        //begintime = gettime(); //don't touch

        if(HI_SUCCESS == flgRenew)
        {
            flgRenew = HI_FAILURE;
            //显示图像
            //pPreBuffer是机顶盒分辨率1280*720，在客户端显示前需进行缩放！
            s32ret = g_surface_Opera.pf_update(pPreBuffer);
            if(HI_SUCCESS != s32ret)
            {
                LOGE("BmpSurfaceDisplay failed!");
                continue;
            }
        }
        else
        {
            //尽快刷新屏幕
            usleep(5);
        }
    }

    return HI_SUCCESS;
}

//获取JPEG解码平均帧率
int HI_NativeSurface_GetDecodeFPS()
{
    return (int)((1000000/DecodeTimeCost)-1);
}

//初始化 SurfaceOperation ，根据安卓系统版本使用不同的函数
static int HI_NativeSurface_Init(JNIEnv* env,jobject jsurface,int apiVersion,
    PF_ANWindow_setBuffersGeometry* pf_setBuffersGeometry)
{
    LOGD("enter HI_NativeSurface_Init");
    memset(&g_surface_Opera, 0, sizeof(SurfaceOperation));
    g_surface_Opera.mAndroidAPIVersion = apiVersion;

    if(g_surface_Opera.mAndroidAPIVersion < ANDROID_VERSION_2_3)
    {
        g_surface_Opera.pf_register = froyo_NativeRegisterSurface;
        g_surface_Opera.pf_update= froyo_NativeUpdateSurface;
        g_surface_Opera.pf_unregister = froyo_NativeUnRegisterSurface;
        g_surface_Opera.pf_setBuffersGeometry = pf_setBuffersGeometry;
        g_surface_Opera.pLibHandle = LoadFroyoLib(LIB_SURFACE_FLINGER_CLIENT_FOR_ANDROID_2_2);
        if(NULL == g_surface_Opera.pLibHandle)
        {
            g_surface_Opera.pLibHandle = LoadFroyoLib(LIB_UI_FOR_ANDROID_2_2);
            if(NULL == g_surface_Opera.pLibHandle)
            {
                LOGE("load libui.so and libsurfaceflinger_client.so failed");
                return HI_FAILURE;
            }
        }
    }
    else
    {
        g_surface_Opera.pf_register = ICS_NativeRegisterSurface;
        g_surface_Opera.pf_update= ICS_NativeUpdateSurface;
        g_surface_Opera.pf_unregister = ICS_NativeUnRegisterSurface;
        g_surface_Opera.pLibHandle = dlopen(LIB_ANDROID_FOR_ANDROID_2_3, RTLD_NOW);
        if(NULL == g_surface_Opera.pLibHandle)
        {
            LOGE("load libandroid.so failed");
             return HI_FAILURE;
        }
        g_surface_Opera.pf_lock = (PF_ANWindow_lock*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_LOCK));
        g_surface_Opera.pf_unlockAndPost = (PF_ANWindow_unlockAndPost*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_UNLOCK));
        //ANativeWindow_getWidth
        g_surface_Opera.pf_getwidth = (PF_ANWindow_getwidth*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_GETWIDTH));
        //ANativeWindow_getHeight
        g_surface_Opera.pf_getheight = (PF_ANWindow_getheight*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_GETHEIGHT));
        g_surface_Opera.pf_release = (PF_ANWindow_release*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_RELEASE));
        g_surface_Opera.pf_get = (PF_ANWindow_get*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_GET));
        g_surface_Opera.pf_setBuffersGeometry= (PF_ANWindow_setBuffersGeometry*)(dlsym(g_surface_Opera.pLibHandle, ANDROID_V23_ANW_SETBUFFERSGEOMETRY));
    }
    //surface to ANativeWindow
    g_surface_Opera.pSurfaceNative = g_surface_Opera.pf_register(&g_surface_Opera,env,jsurface);
    LOGD("after HI_NativeSurface_Init");
    return HI_SUCCESS;
}

//Surface建立时调用
//onCreate
int HI_NativeSurface_SetEnable(JNIEnv * env, jobject jsurface, int apiVersion,jstring ip)
{
    accessip = env->GetStringUTFChars(ip,0);

    if(!g_surface_Opera.pSurfaceNative)
    {
        //first enter
        HI_NativeSurface_Init(env,jsurface,apiVersion,NULL);
        g_surface_Opera.status = DISPLAY_STATUS_INIT;
    }
    else
    {
        //not the first time
        //surface to ANativeWindow
        g_surface_Opera.pSurfaceNative = g_surface_Opera.pf_register(&g_surface_Opera,env,jsurface);
    }

    if(g_surface_Opera.pSurfaceNative)
    {
        if(DISPLAY_STATUS_INIT == g_surface_Opera.status)
        {
            native_window_set_scaling_mode((ANativeWindow*)g_surface_Opera.pSurfaceNative, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
            native_window_set_buffers_geometry((ANativeWindow*)g_surface_Opera.pSurfaceNative, HI_MIRROR_JPEG_MAX_WIDTH,HI_MIRROR_JPEG_MAX_HEIGHT, HAL_PIXEL_FORMAT_RGB_565);
            g_surface_Opera.status = DISPLAY_STATUS_RUN;
            recv_JpegAddr = (char *) malloc(HI_MIRROR_JPEG_BUFFER_LENGTH);
            if(recv_JpegAddr == NULL)
            {
               LOGE("recv_JpegAddr malloc failed.");
               return HI_FAILURE;
            }
            decode_JpegAddr = (char *) malloc(HI_MIRROR_JPEG_BUFFER_LENGTH);
            if(decode_JpegAddr == NULL)
            {
               LOGE("decode_JpegAddr malloc failed.");
               return HI_FAILURE;
            }
            pthread_mutex_init (&mutex,NULL);
            pthread_create(&g_surface_Opera.threadID, NULL,native_receive_process, NULL);
            pthread_create(&g_surface_Opera.pidDecode, NULL,native_decode_process, NULL);
            pthread_create(&g_surface_Opera.pidSurfaceUpdate,NULL, surface_auto_renew, NULL); //刷新线程
        }
        else if(DISPLAY_STATUS_RUN == g_surface_Opera.status)
        {
            LOGD("surfaceNative renew.");
        }
    }

    return HI_SUCCESS;
}

//Surface销毁时调用
//onDestroy
int HI_NativeSurface_DeInit(void* pHandle)
{
    g_surface_Opera.status = DISPLAY_STATUS_STOP;
    pthread_join(g_surface_Opera.threadID, NULL);
    pthread_join(g_surface_Opera.pidDecode, NULL);
    pthread_join(g_surface_Opera.pidSurfaceUpdate, NULL); //刷新线程
    g_surface_Opera.pf_unregister(NULL);

    if(recv_JpegAddr)
    {
        free(recv_JpegAddr);
        recv_JpegAddr = NULL;
    }

    if(decode_JpegAddr)
    {
        free(decode_JpegAddr);
        decode_JpegAddr = NULL;
    }

    if(lutH)
    {
        free(lutH);
        lutH = NULL;
    }

    if(lutW)
    {
        free(lutW);
        lutW = NULL;
    }

    if(pPreBuffer)
    {
        free(pPreBuffer);
        pPreBuffer = NULL;
    }

    g_surface_Opera.pSurfaceNative = NULL;

    return HI_SUCCESS;
}
